package thunderbirdgtd;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

import thunderbirdgtd.entities.Action;
import thunderbirdgtd.entities.BaseActionOrProject;
import thunderbirdgtd.entities.Project;
import thunderbirdgtd.entities.Tag;

public class GTDParent {
	public LinkedList<Project> projects = new LinkedList<Project>();
	public LinkedList<Action> actions = new LinkedList<Action>();
	public LinkedList<Tag> tags = new LinkedList<Tag>();
	public int nParentProjects = 0;
	
	public GTDParent(){
		
		
		
	}
	
	public void setNParentProjects(int num) {
		nParentProjects = num;
	}
	
	public void removeAction(Action a){
		a.getParentProject().removeAction(a);
		actions.remove(a);
	}
	public void removeProject(Project p){
		
		ListIterator<Project> li = p.assignedProjects.listIterator();
		Project p2;
		while(li.hasNext()){
			p2 = li.next();
			removeProject(p2);			
		}

		if(p.getParentProject() == null)
			nParentProjects--;
		projects.remove(p);
	}
	
	public void addAction(Action a, Project p){
		actions.add(a);
		try {
			p.addAction(a);
			a.setParentProject(p);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void addTag(Tag t, BaseActionOrProject bap){
		tags.add(t);
		try {
			bap.addTag(t);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void addProject(Project project) throws Exception {
		
		
		if (project==null)
			throw new Exception("Null project to add.");
		if (projects == null)
			projects = new LinkedList<Project>();
		
		if (Project.searchProjectInLinkedList(project.getName(), projects) == null)	
			projects.add(project);
		else
			throw new Exception("Project already added.");
		nParentProjects++;
	}
	
	public void addChildProject(Project parent, Project child){
		nParentProjects--;
		
		parent.assignedProjects.add(child);
		child.setParentProject(parent);
		
	}
	
	public void removeProject(String projectName) throws Exception {
		
		if (projectName == null)
			throw new Exception("Null tag to remove.");
		if (projects == null)
			throw new Exception("No tags at all.");
		Project p = Project.searchProjectInLinkedList(projectName, projects);
		if(p.getParentProject() == null)
			nParentProjects--;
		if (p==null)
			throw new Exception("No tag found.");
		else
			projects.remove(p);
	}
	
	
	public static void main(String [] args){
		GTDParent gtd = new GTDParent();
		gtd.projects = new LinkedList<Project>();

		
		
		// Example run
		for(int i=0; i<5; i++) {
			gtd.projects.add(new Project("project_"+i));
		}
		
		Iterator<Project> iterator = gtd.projects.iterator();
		
		System.out.println("Projects:");
		while(iterator.hasNext()) {
			Project project = iterator.next();
			
			System.out.println("Name: " + project.getName());
		}
	}


	public LinkedList<BaseActionOrProject> findByTag(String tagName) {
		LinkedList<BaseActionOrProject> finalResults = new LinkedList<BaseActionOrProject>();
		
		finalResults = findByTag(projects, tagName);
		
		return finalResults;
	}
	
	private LinkedList<BaseActionOrProject> findByTag(LinkedList<Project> ps, String tagName) {
		LinkedList<BaseActionOrProject> finalResults = new LinkedList<BaseActionOrProject>();
		
		Iterator<Project> iterator = ps.iterator();
		while(iterator.hasNext()) {
			Project tempProject = iterator.next();
			
			// Check current project
			if(tempProject.hasTag(new Tag(tagName))) {
				finalResults.add(tempProject);
			}
			
			LinkedList<Project> subProjects = tempProject.getSubProjects();

			// If it has subprojects
			if(tempProject.getSubProjects().size() > 0) {
				// Find in subprojects
				finalResults.addAll(findByTag(subProjects, tagName));
			}
			
			Iterator<Action> actionIterator = tempProject.getActions().iterator();
			
			while(actionIterator.hasNext()) {
				Action tempAction = actionIterator.next();
				
				if(tempAction.hasTag(new Tag(tagName))) {
					finalResults.add(tempAction);
				}
			}
		}
		
		return finalResults;
	}
	
	
}
